/* vte */
import { ConfigEnv, defineConfig, UserConfig } from 'vite';
/* plugin */
import { createVuePlugin } from 'vite-plugin-vue2-jsx';
import commonjs from 'vite-plugin-commonjs';
/* util */
import path from 'path';
import { merge } from 'webpack-merge';

import nodeProxyConfig, { localeRunPort } from './server/util/NodeProxyConfig.js';
const { port: proxyPort, headerSign } = nodeProxyConfig;

const genAliasPath = (url: string) => path.resolve(__dirname, url);

const alias = {
  'app.config': genAliasPath('./src/config/development.js'),
  '@src': genAliasPath('./src'),
  '@form': genAliasPath('./src/component/form'),
  '@formComponents': genAliasPath('./src/component/form/components'),
  '@model': genAliasPath('./model'),
  '@service': genAliasPath('./service'),
  '@server': genAliasPath('./server'),
  '@hooks': genAliasPath('./hooks'),
  'src': genAliasPath('./src'),
  'packages': genAliasPath('./packages'),
  '~element-ui': genAliasPath('./node_modules/element-ui'),
  'vue': 'vue/dist/vue.runtime.esm.js',
  '@account': genAliasPath('./src/modules/account'),
  '@tenant': genAliasPath('./src/modules/tenant'),
  '@version': genAliasPath('./src/modules/version'),
  "@gpt": genAliasPath('./src/modules/setting/gpt'),
}

const proxyModule = ['/pcModule/', '/pcoperation/', '/foundation/', '/setting/serviceStation/main', '/pcResourceManage/', '/paas/', '/paas', '/api', '/warehouse/'];

function genProxy() {
  const proxy: any = {};
  proxyModule.forEach(key => {
    return (proxy[key] = {
      target: `http://localhost:${proxyPort}`,
      changeOrigin: true,
    });
  });
  return proxy;
}

/**
 * @description 获取基础配置
 */
function getBaseConfig(): UserConfig {
  return {
    resolve: {
      /**
       * @see https://cn.vitejs.dev/config/shared-options.html#resolve-alias
       */
      alias,
      /**
       * @see https://cn.vitejs.dev/config/shared-options.html#resolve-extensions
       */
      extensions: ['.js', '.json', '.vue', '.ts', '.jsx', '.tsx', '.scss', '.css'], // 保持和webpack一致
      // [
      //   '.js',
      //   '.mjs',
      //   '.jsx',
      //   '.ts',
      //   '.tsx',
      //   '.vue',
      //   '.json',
      //   '.css',
      //   '.scss',
      //   '.wasm',
      // ]
    },
    /**
     * @see https://cn.vitejs.dev/config/server-options.html
     */
    server: {
      host: '0.0.0.0',
      port: localeRunPort,
      proxy: {
        // 选项写法
        '/serve/': {
          target: `http://localhost:${proxyPort}`,
          changeOrigin: true,
          rewrite: path => {
            const reg = new RegExp(headerSign);
            return path.replace(reg, '');
          },
        },
        // 直接代理，/resource/会和根目录下的resource文件冲突，导致使用resource文件夹下的资源的页面打不开
        '/resource111/': {
          target: `http://localhost:${proxyPort}${headerSign}`,
          changeOrigin: true,
        },
        ...genProxy(),
      },
    },
    css: {
      /**
       * @see https://cn.vitejs.dev/config/shared-options.html#css-devsourcemap
       */
      devSourcemap: false,
      /**
       * @see https://cn.vitejs.dev/config/shared-options.html#css-preprocessoroptions
       */
      preprocessorOptions: {
        scss: {
          // 添加公共样式
          additionalData: `
            @import "./src/assets/scss/theme_color/index.scss"; 
            @import "./src/assets/scss/_themes.scss"; 
            @import "./src/assets/scss/_variables.scss";
            @import "./src/assets/scss/_mixins.scss";
          `,
        },
      },
      postcss: {
        plugins: [
          {
            postcssPlugin: 'internal:charset-removal',
            AtRule: {
              charset: atRule => {
                if (atRule.name === 'charset') {
                  atRule.remove();
                }
              },
            },
          },
        ],
      },
    },
    /**
     * @see https://cn.vitejs.dev/config/shared-options.html#base
     */
    base: '/',
    /**
     * @see https://cn.vitejs.dev/config/build-options.html
     */
    build: {
      chunkSizeWarningLimit: 4000,
    },
    optimizeDeps: {
      include: ['@vue/babel-helper-vue-jsx-merge-props'],
      exclude: ['codemirror']
    },
    /**
     * @see https://cn.vitejs.dev/plugins/
     */
    plugins: [
      createVuePlugin({
        target: 'esnext',
        jsx: true,
        jsxOptions: {
          compositionAPI: true 
        }
      }),
      commonjs(),
    ],
  };
}

/**
 * @description 获取开发配置
 */
function getDevelopmentConfig(): UserConfig {
  return {
    resolve: {
      alias: {
        // 'pub-bbx-utils': genAliasPath('../pub-bbx-utils/lib/index.mjs'),
        'pub-bbx-global/lang/dist': path.resolve(__dirname, '../pub-bbx-global/lang'),
        'pub-bbx-global/pageType/dist': path.resolve(__dirname, '../pub-bbx-global/pageType'),
        'pub-bbx-global': path.resolve(__dirname, '../pub-bbx-global'),
        // 'pub-bbx-api':genAliasPath('../pub-bbx-api/lib/index.js'),
        // "pub-bbx-pc-vue2/style": path.resolve(__dirname, "../pub-bbx-pc-vue2/lib/theme/index.css"),
        // "pub-bbx-pc-vue2": path.resolve(__dirname, "../pub-bbx-pc-vue2"),
      },
    },
    optimizeDeps: {
      // exclude: ['pub-bbx-global', 'pun-bbx-utils'],
    },
    plugins: [
      /**
       * @see https://github.com/webfansplz/vite-plugin-vue-inspector
       */
      // Inspector({
      //   vue: 2,
      // }),
    ],
  };
}

/**
 * @description 获取生产配置
 */
function getProductionConfig(): UserConfig {
  return {
    resolve: {
      alias: {
        'app.config': path.resolve(__dirname, './src/config/production.js'),
      },
    },
    build: {
      target: 'es2015',
    },
    /**
     * @see https://cn.vitejs.dev/config/shared-options.html#base
     */
    base: '/resource/pc-fe/',
  };
}

export default defineConfig((env: ConfigEnv) => {
  /**
   * @see https://cn.vitejs.dev/config/shared-options.html#mode
   */
  const mode = env.mode;

  // 是否为开发环境
  const __DEV__ = mode === 'development';

  // 基础配置
  const baseConfig = getBaseConfig();

  // 当前环境对应的配置
  const currentModeConfig = __DEV__ ? getDevelopmentConfig() : getProductionConfig();

  // 合并配置
  const config = merge(baseConfig, currentModeConfig);

  return config;
});
